// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.core.textures;

import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.CRC32;

public final class PNGSize {
    private static final byte[] SIGNATURE = new byte[]{-119, 80, 78, 71, 13, 10, 26, 10};
    private static final int IHDR = 1229472850;
    public int width;
    public int height;
    private int bitdepth;
    private int colorType;
    private int bytesPerPixel;
    private InputStream input;
    private final CRC32 crc = new CRC32();
    private final byte[] buffer = new byte[4096];
    private int chunkLength;
    private int chunkType;
    private int chunkRemaining;

    public void readSize(String path) {
        try {
            FileInputStream fileInputStream = new FileInputStream(path);

            try {
                BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

                try {
                    this.readSize(bufferedInputStream);
                } catch (Throwable throwable0) {
                    try {
                        bufferedInputStream.close();
                    } catch (Throwable throwable1) {
                        throwable0.addSuppressed(throwable1);
                    }

                    throw throwable0;
                }

                bufferedInputStream.close();
            } catch (Throwable throwable2) {
                try {
                    fileInputStream.close();
                } catch (Throwable throwable3) {
                    throwable2.addSuppressed(throwable3);
                }

                throw throwable2;
            }

            fileInputStream.close();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    public void readSize(InputStream _input) throws IOException {
        this.input = _input;
        this.readFully(this.buffer, 0, SIGNATURE.length);
        if (!this.checkSignature(this.buffer)) {
            throw new IOException("Not a valid PNG file");
        } else {
            this.openChunk(1229472850);
            this.readIHDR();
            this.closeChunk();
        }
    }

    private void readIHDR() throws IOException {
        this.checkChunkLength(13);
        this.readChunk(this.buffer, 0, 13);
        this.width = this.readInt(this.buffer, 0);
        this.height = this.readInt(this.buffer, 4);
        this.bitdepth = this.buffer[8] & 255;
        this.colorType = this.buffer[9] & 255;
    }

    private void openChunk() throws IOException {
        this.readFully(this.buffer, 0, 8);
        this.chunkLength = this.readInt(this.buffer, 0);
        this.chunkType = this.readInt(this.buffer, 4);
        this.chunkRemaining = this.chunkLength;
        this.crc.reset();
        this.crc.update(this.buffer, 4, 4);
    }

    private void openChunk(int _int) throws IOException {
        this.openChunk();
        if (this.chunkType != _int) {
            throw new IOException("Expected chunk: " + Integer.toHexString(_int));
        }
    }

    private void closeChunk() throws IOException {
        if (this.chunkRemaining > 0) {
            this.skip((long)(this.chunkRemaining + 4));
        } else {
            this.readFully(this.buffer, 0, 4);
            int int0 = this.readInt(this.buffer, 0);
            int int1 = (int)this.crc.getValue();
            if (int1 != int0) {
                throw new IOException("Invalid CRC");
            }
        }

        this.chunkRemaining = 0;
        this.chunkLength = 0;
        this.chunkType = 0;
    }

    private void checkChunkLength(int _int) throws IOException {
        if (this.chunkLength != _int) {
            throw new IOException("Chunk has wrong size");
        }
    }

    private int readChunk(byte[] _byte, int int1, int int0) throws IOException {
        if (int0 > this.chunkRemaining) {
            int0 = this.chunkRemaining;
        }

        this.readFully(_byte, int1, int0);
        this.crc.update(_byte, int1, int0);
        this.chunkRemaining -= int0;
        return int0;
    }

    private void readFully(byte[] _byte, int int1, int int2) throws IOException {
        do {
            int int0 = this.input.read(_byte, int1, int2);
            if (int0 < 0) {
                throw new EOFException();
            }

            int1 += int0;
            int2 -= int0;
        } while (int2 > 0);
    }

    private int readInt(byte[] _byte, int _int) {
        return _byte[_int] << 24 | (_byte[_int + 1] & 0xFF) << 16 | (_byte[_int + 2] & 0xFF) << 8 | _byte[_int + 3] & 0xFF;
    }

    private void skip(long long0) throws IOException {
        while (long0 > 0L) {
            long long1 = this.input.skip(long0);
            if (long1 < 0L) {
                throw new EOFException();
            }

            long0 -= long1;
        }
    }

    private boolean checkSignature(byte[] _byte) {
        for (int _int = 0; _int < SIGNATURE.length; _int++) {
            if (_byte[_int] != SIGNATURE[_int]) {
                return false;
            }
        }

        return true;
    }
}
